/*
 * @Author       : 李跃建
 * @Date         : 2023-02-12 18:53:35
 * @LastEditors  : [you name]
 * @LastEditTime : 2023-02-13 16:45:46
 */
(function () {
	window.addEventListener('DOMContentLoaded', function () {
		main();
	});

	/**
	 * @Date         : 2023-02-12 21:14:26
	 * @description  : 初始化
	 * @return        {*}
	 */
	function main() {
		drawMap();
		drawSnake();
		drawFood();
		bindEvent();
		automation();
	}

	/**
	 * @Date         : 2023-02-12 21:13:10
	 * @description  : 绘制地图(初始化地图)
	 * @param         {Number} rowCount:
	 * @param         {Number} cloCount:
	 * @return        {*}
	 */
	function drawMap() {
		let container = document.querySelector('.container');
		for (let i = 0; i < rowCount; i++) {
			for (let j = 0; j < cloCount; j++) {
				let div = document.createElement('div');
				div.className = 'physical';
				container.appendChild(div);
				map.push({ x: j, y: i });
			}
		}
	}

	/**
	 * @Date         : 2023-02-12 22:52:33
	 * @description  : 绘制蛇身
	 * @param         {Object} snake:
	 * @param         {Number} snakeBody:
	 * @return        {*}
	 */
	function drawSnake() {
		const container = document.querySelector('.container');
		for (let i = 0; i < snake.snakePosition.length; i++) {
			if (!snake.snakePosition[i].domContent) {
				snake.snakePosition[i].domContent = document.createElement('div');
				snake.snakePosition[i].domContent.style.width = snakeBody + 'px';
				snake.snakePosition[i].domContent.style.height = snakeBody + 'px';
				snake.snakePosition[i].domContent.style.top = snake.snakePosition[i].y * snakeBody + 'px';
				snake.snakePosition[i].domContent.style.left = snake.snakePosition[i].x * snakeBody + 'px';
				if (snake.snakePosition[i].flag === 'head') {
					snake.snakePosition[i].domContent.className = 'snakeHead';
				} else {
					snake.snakePosition[i].domContent.className = 'snakeBody';
				}
				container.appendChild(snake.snakePosition[i].domContent);
			}
		}
	}

	/**
	 * @Date         : 2023-02-13 13:44:51
	 * @description  : 绘制食物
	 * @param         {Object} snake:
	 * @param         {Object} food:
	 * @param         {Number} rowCount:
	 * @param         {Number} cloCount:
	 * @param         {Number} snakeBody:
	 * @return        {*}
	 */
	function drawFood() {
		// 生成食物前将旧食物清除
		if (food.domContent) {
			document.querySelector('.container').removeChild(food.domContent);
		}
		while (true) {
			// 判断食物是否绘制到蛇身上
			let isRepeat = false;
			food.x = Math.floor(Math.random() * rowCount);
			food.y = Math.floor(Math.random() * cloCount);
			for (let i = 0; i < snake.snakePosition.length; i++) {
				if (snake.snakePosition[i].x === food.x && snake.snakePosition[i].y === food.y) {
					// 食物与绘制到蛇身了
					isRepeat = true;
					break;
				}
			}
			if (!isRepeat) {
				food.domContent = document.createElement('div');
				food.domContent.style.width = snakeBody + 'px';
				food.domContent.style.height = snakeBody + 'px';
				food.domContent.style.top = food.y * snakeBody + 'px';
				food.domContent.style.left = food.x * snakeBody + 'px';
				food.domContent.className = 'food';
				document.querySelector('.container').appendChild(food.domContent);
				break;
			}
		}
	}

	/**
	 * @Date         : 2023-02-13 14:08:48
	 * @description  : 绑定事件
	 * @param         {Object} snake:
	 * @param         {Object} snakeDirection:
	 * @return        {*}
	 */
	function bindEvent() {
		document.addEventListener('keydown', function (e) {
			// 判断游戏是否结束 初始化时false
			if (isEnd) {
				return;
			} else {
				if (e.key === 'w' || e.key === 'ArrowUp') {
					snake.defaultOrientation = snakeDirection.top;
				} else if (e.key === 's' || e.key === 'ArrowDown') {
					snake.defaultOrientation = snakeDirection.bottom;
				} else if (e.key === 'a' || e.key === 'ArrowLeft') {
					snake.defaultOrientation = snakeDirection.left;
				} else if (e.key === 'd' || e.key === 'ArrowRight') {
					snake.defaultOrientation = snakeDirection.right;
				} else {
					return;
				}
				snakeMove(snake);
			}
		});
	}

	/**
	 * @Date         : 2023-02-13 14:40:26
	 * @description  : 蛇的移动
	 * @param         {Object} snake:
	 * @return        {*}
	 */
	function snakeMove() {
		// 旧蛇头的位置
		oldHead = snake.snakePosition[snake.snakePosition.length - 1];
		// 新蛇头的位置
		let newHead = {
			x: oldHead.x + snake.defaultOrientation.x,
			y: oldHead.y + snake.defaultOrientation.y,
			domContent: '',
			flag: 'head',
		};
		// 用新蛇头位置检测是否碰撞
		let colliders = isCollide(newHead);
		// 碰撞墙壁或蛇体
		if (colliders.isCollide || colliders.isBody) {
			const end = confirm('游戏结束，点击确定按钮重新开始！');
			if (end) {
				location.reload();
			} else {
				isEnd = true;
				clearInterval(timerStop);
				return;
			}
		}
		// 吃到食物
		if (colliders.isEat) {
			drawFood();
		} else {
			document.querySelector('.container').removeChild(snake.snakePosition[0].domContent);
			snake.snakePosition.shift();
		}
		oldHead.flag = 'body';
		document.querySelector('.container').removeChild(oldHead.domContent);
		oldHead.domContent = '';
		snake.snakePosition.push(newHead);
		// 重新绘制蛇
		drawSnake();
	}

	/**
	 * @Date         : 2023-02-13 15:22:38
	 * @description  : 检测是否碰撞
	 * @param         {Object} snake:
	 * @param         {Object} newHead:
	 * @param         {Object} food:
	 * @param         {Number} rowCount:
	 * @param         {Number} cloCount:
	 * @return        {Object}
	 */
	function isCollide(newHead) {
		let colliders = {
			isCollide: false, // 是否碰到墙体
			isBody: false, // 是否碰到蛇身
			isEat: false, // 是否碰到食物
		};
		// 检测是否碰到蛇身
		for (let i = 0; i < snake.snakePosition.length; i++) {
			if (snake.snakePosition[i].x === newHead.x && snake.snakePosition[i].y === newHead.y) {
				colliders.isBody = true;
			}
		}
		// 检测是否否碰到墙体
		if (newHead.x < 0 || newHead.x > rowCount - 1 || newHead.y < 0 || newHead.y > cloCount - 1) {
			colliders.isCollide = true;
			return colliders;
		}
		// 检测是否碰到食物
		if (newHead.x === food.x && newHead.y === food.y) {
			colliders.isEat = true;
			return colliders;
		}
		return colliders;
	}

	/**
	 * @Date         : 2023-02-13 16:29:33
	 * @description  : 蛇自动移动
	 * @return        {*}
	 */
	function automation() {
		timerStop = setInterval(() => {
			snakeMove(snake);
		}, timer);
	}
})();
